package com.yenlien.traceyun.usercenter.service;

import com.alibaba.fastjson.JSONObject;
import com.yenlien.traceyun.common.utils.RandomUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.nio.file.Paths;
import java.util.*;

/**
 * Created by LiuSha on 2020/6/18.
 */
@Service
public class FileService {
    public static final String ROOT = "upload";
    @Autowired
    private ResourceLoader resourceLoader;

    public String upload(MultipartFile file) throws IOException {
        File destFile = new File(Paths.get(ROOT).toAbsolutePath().toString());
        if (!destFile.exists()) {
            destFile.mkdirs();
        }
        String type = file.getOriginalFilename().substring(file.getOriginalFilename().indexOf("."));// 取文件格式后缀名
        String filename = System.currentTimeMillis() + "_" + RandomUtil.random(6) + type;// 取当前时间戳作为文件名
        File sourceFile = new File(Paths.get(ROOT, filename).toAbsolutePath().toString());
        file.transferTo(sourceFile);
        return filename;
    }

    public String upload(List<MultipartFile> files, Object form) throws Exception {
        if (files == null || files.size() == 0) {
            return null;
        }
        File destFile = new File(Paths.get(ROOT).toAbsolutePath().toString());
        if (!destFile.exists()) {
            destFile.mkdirs();
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (MultipartFile file : files) {
            String originalFilename = file.getOriginalFilename();
            String type = originalFilename.substring(originalFilename.indexOf("."));// 取文件格式后缀名
            String filename = System.currentTimeMillis() + "_" + RandomUtil.random(6) + type;// 取当前时间戳作为文件名
            File sourceFile = new File(Paths.get(ROOT, filename).toAbsolutePath().toString());
//            file.transferTo(sourceFile);
            saveFile(file.getInputStream(), sourceFile);
            stringBuilder.append(";").append(filename);
            replaceFileName(form, originalFilename, filename);
        }
        if (stringBuilder.length() <= 0) {
            return stringBuilder.toString();
        }
        return stringBuilder.substring(1);
    }

    private void replaceFileName(Object form, String originalFilename, String newName) throws IllegalAccessException {
        for (Field field : form.getClass().getDeclaredFields()) {
            if (field.getName().toLowerCase().endsWith("img")) {
                field.setAccessible(true);
                Object imageValue = field.get(form);
                if (imageValue != null) {
                    String oldValue = imageValue.toString();
                    if (oldValue != null && oldValue.contains(originalFilename)) {
                        field.set(form, oldValue.replace(originalFilename, newName));
                        break;
                    }
                }

            }
        }
    }


    /**
     * @param persitent
     * @param form
     * @param files
     * @return
     */
    public String upload(Object persitent, Object form, List<MultipartFile> files) throws Exception {
        //添加
        if (persitent == null) {
            return upload(files, form);
        } else {//修改
            Field[] fields = form.getClass().getDeclaredFields();
            List<String> deles = new ArrayList<>();
            for (Field field : fields) {
                field.setAccessible(true);
                if (field.getName().toLowerCase().endsWith("img")) {
                    String newValue = field.get(form).toString();
                    Field oldField = persitent.getClass().getDeclaredField(field.getName());
                    oldField.setAccessible(true);
                    String oldValue = null;
                    Object oldObj = oldField.get(persitent);
                    if (oldObj != null) {
                        oldValue = oldObj.toString();
                    }
                    //如果新值为空则全部删除
                    if (StringUtils.isEmpty(newValue)) {
                        if (!StringUtils.isEmpty(oldValue)) {
                            deles.addAll(Arrays.asList(oldValue.split(";")));
                        }
                    } else {
                        if (!StringUtils.isEmpty(oldValue)) {
                            List<String> oldlist = new ArrayList(Arrays.asList(oldValue.split(";")));
                            List<String> newlist = new ArrayList(Arrays.asList(newValue.split(";")));
                            oldlist.removeAll(newlist);
                            if (oldlist.size() > 0) {
                                deles.addAll(oldlist);
                            }
                        }
                    }
                }
            }
            deleteFiles(deles);
            return upload(files, form);
        }
    }

    public void deleteFile(String filename) throws IOException {
        File file = resourceLoader.getResource("file:" + Paths.get(ROOT, filename).toString()).getFile();
        file.delete();
    }

    public void deleteFiles(List<String> files) throws IOException {
        if (files != null && files.size() > 0) {
            for (String filename : files) {
                deleteFile(filename);
            }
        }
    }

    private void saveFile(InputStream is, File dest) {
        try (FileOutputStream fos = new FileOutputStream(dest)) {
            int len;
            byte[] buffer = new byte[1024];
            while ((len = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

        }
    }


    //替换图片
    public void replaceImg(Object obj) throws IllegalAccessException, IOException {
        Field[] fields = obj.getClass().getDeclaredFields();
        JSONObject params = new JSONObject();
        for (Field field : fields) {
            if (field.getName().endsWith("Img")) {
                field.setAccessible(true);
                String name = field.getName().toUpperCase();
                String value = (String) field.get(obj);
                if (!StringUtils.isEmpty(value)) {
                    params.put(name, value);
                }
            }
        }
        if (params.size() > 0) {
            for (String str : params.keySet()) {
                if (str.startsWith("OLD")) {
                    String name = str.substring(3, str.length());
                    Object value = params.get(str);
                    String[] oldFiles = value.toString().split(";");
                    Set<String> set = new HashSet<>(Arrays.asList(oldFiles));
                    for (String st : params.keySet()) {
                        if (st.equals(name)) {
                            Object va = params.get(st);
                            String[] file = va.toString().split(";");
                            for (String keep : file) {
                                if (set.contains(keep)) {
                                    set.remove(keep);
                                }
                            }
                            if (set.size() > 0) {
                                for (String del : set) {
                                    deleteFile(del);
                                }
                            }
                        }
                    }
                }
            }
        }
    }


    //替换图片(url结尾)
    public void replaceUrl(Object obj) throws IllegalAccessException, IOException {
        Field[] fields = obj.getClass().getDeclaredFields();
        JSONObject params = new JSONObject();
        for (Field field : fields) {
            if (field.getName().endsWith("Url")) {
                field.setAccessible(true);
                String name = field.getName().toUpperCase();
                String value = (String) field.get(obj);
                if (!StringUtils.isEmpty(value)) {
                    params.put(name, value);
                }
            }
        }
        if (params.size() > 0) {
            for (String str : params.keySet()) {
                if (str.startsWith("OLD")) {
                    String name = str.substring(3, str.length());
                    Object value = params.get(str);
                    String[] oldFiles = value.toString().split(",");
                    Set<String> set = new HashSet<>(Arrays.asList(oldFiles));
                    for (String st : params.keySet()) {
                        if (st.equals(name)) {
                            Object va = params.get(st);
                            String[] file = va.toString().split(",");
                            for (String keep : file) {
                                if (set.contains(keep)) {
                                    set.remove(keep);
                                }
                            }
                            if (set.size() > 0) {
                                for (String del : set) {
                                    deleteFile(del);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
